package com.itheima.stock.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.stock.constant.StockConstant;
import com.itheima.stock.mapper.SysPermissionMapper;
import com.itheima.stock.mapper.SysRoleMapper;
import com.itheima.stock.mapper.SysUserRoleMapper;
import com.itheima.stock.pojo.domain.*;
import com.itheima.stock.pojo.entity.SysPermission;
import com.itheima.stock.pojo.entity.SysRole;
import com.itheima.stock.pojo.entity.SysUser;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.vo.PageResult;
import com.itheima.stock.service.UserService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.utils.Zifuchuang19wei;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("ALL")
@Slf4j
@Service("userService")
public class UserServiceImpl implements UserService {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private Zifuchuang19wei zifuchuang19wei;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    @Override
    public SysUser findByUserName(String userName) {
        return sysUserMapper.findByUserName(userName);
    }
    //登录验证
    @Override
    public R<LoginRespVo> login(LoginReqVo vo) {
//        if (vo==null || StringUtils.isBlank(vo.getUsername()) || StringUtils.isBlank(vo.getPassword())){
//            return R.error(ResponseCode.DATA_ERROR.getMessage());
//        }
//        //根据用户名查询用户信息
//        SysUser user=this.sysUserMapper.findByUserName(vo.getUsername());
//        //判断用户是否存在，存在则密码校验比对
//        if (user==null || !passwordEncoder.matches(vo.getPassword(),user.getPassword())){
//            return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
//        }
//        //组装登录成功数据
//        LoginRespVo respVo = new LoginRespVo();
//        //属性名称与类型必须相同，否则属性值无法copy
//        BeanUtils.copyProperties(user,respVo);
//        return  R.ok(respVo);

        //1.校验参数的合法性
        if (vo==null || StringUtils.isBlank(vo.getUsername()) || StringUtils.isBlank(vo.getPassword())) {
            return R.error(ResponseCode.DATA_ERROR);
        }
        //2.校验验证码和sessionId是否有效
        if (StringUtils.isBlank(vo.getCode()) || StringUtils.isBlank(vo.getSessionId())){
            return R.error(ResponseCode.DATA_ERROR);
        }
        //3.根据Rkey从redis中获取缓存的校验码
        String rCode= (String) redisTemplate.opsForValue().get(StockConstant.CHECK_PREFIX+vo.getSessionId());
        //判断获取的验证码是否存在，以及是否与输入的验证码相同
        if (StringUtils.isBlank(rCode) || ! rCode.equalsIgnoreCase(vo.getCode())) {
            //验证码输入有误
            return R.error(ResponseCode.CHECK_CODE_ERROR);
        }
        //4.根据账户名称去数据库查询获取用户信息
        SysUser dbUser = sysUserMapper.findByUserName(vo.getUsername());
        //5.判断数据库用户是否存在
        if (dbUser==null) {
            return R.error(ResponseCode.ACCOUNT_NOT_EXISTS);
        }
        //6.如果存在，则获取密文密码，然后传入的明文进行匹配,判断是否匹配成功
        if (!passwordEncoder.matches(vo.getPassword(),dbUser.getPassword())) {
            return R.error(ResponseCode.USERNAME_OR_PASSWORD_ERROR);
        }
        //7.正常响应
        LoginRespVo respVo = new LoginRespVo();
        BeanUtils.copyProperties(dbUser,respVo);
        return R.ok(respVo);
    }

    /**
     * 登录校验吗方法实现
     * @return
     */
    @Override
    public R<Map> getCaptchaCode() {
        //参数分别是宽、高、验证码长度、干扰线数量
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(250, 40, 4, 5);
        //设置背景颜色清灰
        captcha.setBackground(Color.lightGray);
        //自定义校验码生成方式
//        captcha.setGenerator(new CodeGenerator() {
//            @Override
//            public String generate() {
//                return RandomStringUtils.randomNumeric(4);
//            }
//            @Override
//            public boolean verify(String code, String userInputCode) {
//                return code.equalsIgnoreCase(userInputCode);
//            }
//        });
        //获取图片中的验证码，默认生成的校验码包含文字和数字，长度为4
        String checkCode = captcha.getCode();
        log.info("生成校验码:{}",checkCode);
        //生成sessionId
        String sessionId = String.valueOf(idWorker.nextId());
        //将sessionId和校验码保存在redis下，并设置缓存中数据存活时间一分钟
        redisTemplate.opsForValue().set(StockConstant.CHECK_PREFIX +sessionId,checkCode,1, TimeUnit.MINUTES);
        //组装响应数据
        HashMap<String, String> info = new HashMap<>();
        info.put("sessionId",sessionId);
        info.put("imageData",captcha.getImageBase64());//获取base64格式的图片数据
        //设置响应数据格式
        return R.ok(info);
    }

    /**
     * 多条件分页查询
     * @param
     * @param
     * @return
     */
    @Override
    public R<PageResult> getUserList(FindUserMultipleCondition condition) {
        if ("".equals(condition.getStartTime())) {
            condition.setStartTime(null);
        }
        if ("".equals(condition.getEndTime())) {
            condition.setEndTime(null);
        }
        if ("".equals(condition.getUsername())){
            condition.setUsername(null);
        }
        if ("".equals(condition.getNickName())){
            condition.setNickName(null);
        }
        if ("".equals(condition.getStatus())){
            condition.setStatus(null);
        }
        int pageSize = condition.getPageSize() != null ? Integer.parseInt(condition.getPageSize()) : 10; // 默认页大小设为10
        int pageNum = condition.getPageNum() != null ? Integer.parseInt(condition.getPageNum()) : 1; // 默认页码设为1
        PageHelper.startPage(pageNum,pageSize);
        List<SysUserMultipleConditionDomain> data = sysUserMapper.getUserList(condition.getUsername(),
                condition.getNickName(),
                condition.getStartTime(),
                condition.getEndTime(),
                condition.getStatus());
        if (CollectionUtils.isEmpty(data)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA);
        }
        PageResult<SysUserMultipleConditionDomain> pageResult = new PageResult<>(new PageInfo<>(data));
        return R.ok(pageResult);
    }

    @Override
    public R AddUser(UserInfoToAdd userInfoToAdd) {
//        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
//        Date curTime = curDateTime.toDate();
        Date curTime = DateTime.now().toDate();
        // 调用UniqueNumberGenerator类的generateUniqueNumber方法生成一个长整型的唯一数字
        long uniqueNumber = zifuchuang19wei.generateUniqueNumberWithPrefix();

        // 使用formatNumber方法将长整型数字转换为19位的字符串
        String id= zifuchuang19wei.formatNumber(uniqueNumber);
        String encode = passwordEncoder.encode(userInfoToAdd.getPassword());
        int flag = sysUserMapper.AddUserInfo(id,userInfoToAdd.getUsername(),
                encode,
                userInfoToAdd.getPhone(),
                userInfoToAdd.getEmail(),
                userInfoToAdd.getNickName(),
                userInfoToAdd.getRealName(),
                userInfoToAdd.getSex(),
                userInfoToAdd.getCreateWhere(),
                userInfoToAdd.getStatus(), curTime);
        if (flag>0){
            return R.ok("操作成功");
        }else {
            return R.error("操作失败");
        }

    }

    @Override
    public R<Map<String, List>> getUserRoleInfo(String userId) {
        Map<String, List> map = new HashMap<>();
        List<String> ownRoleIds = sysUserRoleMapper.getUserRoleInfo(userId);
        List<SysRole> allRole = sysRoleMapper.getAllUserRoleInfo();
        map.put("ownRoleIds",ownRoleIds);
        map.put("allRole",allRole);
        return R.ok(map);
    }

    @Override
    public R addUserRole(UserAddRole userAddRole) {
        Date createTime = DateTime.now().toDate();
        //TODO mock数据,后续删除

        int flag=0;
        ArrayList<Long> roleIds = userAddRole.getRoleIds();
        for (Long roleId : roleIds) {
            long uniqueNumber = zifuchuang19wei.generateUniqueNumberWithPrefix();
            // 使用formatNumber方法将长整型数字转换为19位的字符串
            String id= zifuchuang19wei.formatNumber(uniqueNumber);
            flag+=sysUserRoleMapper.addUserRole(id,userAddRole.getUserId(),roleId,createTime);
        }
        if (flag==roleIds.size()){
            return R.ok("操作成功");
        }else{
            return R.ok("操作成功");
        }

    }

    @Override
    public R deleteUserInfo(List<Long> userIds) {
        int flag=0;
        for (Long userId : userIds) {
            flag+=sysUserMapper.deleteByPrimaryKey(userId);
        }
        if (flag==userIds.size()){
            return R.ok("操作成功");
        }else{
            return R.ok("操作成功");
        }
    }

    @Override
    public R<SysInfoById> getUserInfoById(Long userId) {
        SysInfoById data = sysUserMapper.getUserInfoById(userId);
        return R.ok(data);
    }

    @Override
    public R updateUserInfoById(SysInfoByIdToUpDate sysInfoByIdToUpDate) {
        int flag=0;
        flag+=sysUserMapper.updateUserInfoById(sysInfoByIdToUpDate.getUsername(),
                sysInfoByIdToUpDate.getPhone(),
                sysInfoByIdToUpDate.getEmail(),
                sysInfoByIdToUpDate.getNickName(),
                sysInfoByIdToUpDate.getRealName(),
                sysInfoByIdToUpDate.getSex(),
                sysInfoByIdToUpDate.getCreateWhere(),
                sysInfoByIdToUpDate.getStatus(),sysInfoByIdToUpDate.getId());
        if (flag>0){
            return R.ok("操作成功");
        }else {
            return R.error("操作失败");
        }
    }

    @Override
    public R<PageResult> getUserRoleList(FenyeForRole condition) {
        int pageSize = condition.getPageSize() != null ? Integer.parseInt(condition.getPageSize()) : 10; // 默认页大小设为10
        int pageNum = condition.getPageNum() != null ? Integer.parseInt(condition.getPageNum()) : 1; // 默认页码设为1
        PageHelper.startPage(pageNum,pageSize);
        List<SysRole> data = sysRoleMapper.getUserRoleList();
        if (CollectionUtils.isEmpty(data)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA);
        }
        PageResult<SysRole> pageResult = new PageResult<>(new PageInfo<>(data));
        return R.ok(pageResult);
    }

    @Override
    public R deleteRoleById(Long roleId) {
        int flag = 0;
        flag+=sysRoleMapper.deleteRoleById(roleId);
        if (flag>0){
            return R.ok("操作成功");
        }else {
            return R.error("操作失败");
        }
    }

    @Override
    public R updateUserStatus(Long roleId,Integer status) {
        int flag=0;
        flag+=sysRoleMapper.updateUserStatus(roleId,status);
        if (flag>0){
            return R.ok("操作成功");
        }else {
            return R.error("操作失败");
        }
    }

    @Override
    public R<List<SysPermission>> getPermissionList() {
        List<SysPermission> data = sysPermissionMapper.getPermissionList();
        return R.ok(data);
    }

    @Override
    public R<List<PermissionTree>> getPermissionTree() {
        List<PermissionTree> data = sysPermissionMapper.getPermissionTree();
        return R.ok(data);
    }

    @Override
    public R<PermissionForAdd> addPermission(PermissionForAdd permissionForAdd) {
        int flag = 0;
        long l = zifuchuang19wei.generateUniqueNumberWithPrefix();
        String id= zifuchuang19wei.formatNumber(l);
        flag+=sysPermissionMapper.addPermission(
                id,permissionForAdd.getType(),
                permissionForAdd.getTitle(),
                permissionForAdd.getPid(),
                permissionForAdd.getUrl(),
                permissionForAdd.getName(),
                permissionForAdd.getIcon(),
                permissionForAdd.getPerms(),
                permissionForAdd.getMethod(),
                permissionForAdd.getCode(),
                permissionForAdd.getOrderNum());
        if (flag>0){
            return R.ok("添加成功");
        }else {
            return R.error("添加失败");
        }

    }

    @Override
    public R updatePermission(PermissionForUpdate permissionForUpdate) {
        int flag = 0;
        flag+=sysPermissionMapper.updatePermission(permissionForUpdate.getId(),
                                                    permissionForUpdate.getType(),
                                                    permissionForUpdate.getTitle(),
                                                    permissionForUpdate.getPid(),
                                                    permissionForUpdate.getUrl(),
                                                    permissionForUpdate.getName(),
                                                    permissionForUpdate.getIcon(),
                                                    permissionForUpdate.getPerms(),
                                                    permissionForUpdate.getMethod(),
                                                    permissionForUpdate.getCode(),
                                                    permissionForUpdate.getOrderNum());
        if (flag>0){
            return R.ok("操作成功");
        }else {
            return R.error("操作失败");
        }
    }

    @Override
    public R deletePermission(Long permissionId) {
        int flag = 0;
        flag+=sysPermissionMapper.deletePermission(permissionId);
        if (flag>0){
            return R.ok("操作成功");
        }else {
            return R.error("操作失败");
        }
    }
}

